import random
import re
import uuid

from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput

from cash_pos.constants.common_sequence import SWITCH_ENV
from cash_pos.function.common_function import CommonFunction
from cash_pos.model.pay_detail import PayDetail
from cash_pos.page.pay_page.casher_detail_page import CasherDetailPage
from cash_pos.constants.common_sequence import PaymentMethod, PayWay, BusinessDiscountType


class PayOutPage(object):

    def __init__(self, client):
        self.client = client
        self.driver = client.driver
        self.width = client.width
        self.height = client.height

    """
    Subpage Function
    """

    def switch_discount_way(self, business_discount_type):
        """
        切换折扣方式
        """
        if business_discount_type == BusinessDiscountType.fixamount.value:
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_shop_discount_type_2').click()
        if business_discount_type == BusinessDiscountType.fixdiscount.value:
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_shop_discount_type_1').click()
        return self

    """
    Button Function
    """

    def receive_payment(self):
        """
        收款
        """
        # TODO 需要优化
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_submit_pay').click()

    def preliminary_bill(self):
        """
        打印预结单
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_print_receipts_view').click()
        return self

    def open_cash_drawer(self):
        """
        打开钱箱
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_open_cash_box').click()
        return self

    def according_dish(self):
        """
        根据菜品分单
        """
        self.driver.implicitly_wait(1)
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/splitByDishButton').click()
        # TODO 加入根据菜品进行分单的逻辑

    def according_person(self):
        """
        根据人数分单
        """
        self.driver.implicitly_wait(1)
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/splitByPeopleButton').click()
        # TODO 加入根据人数进行分单的逻辑

    def action_pay(self):
        """
        收款
        """
        # 收款的英文
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_submit_pay').click()
        return CasherDetailPage(self.client)

    def use_coupon(self):
        """
        使用优惠券
        """
        from cash_pos.page.security_page.coupon_page import CouponSearchPage
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/useCouponButton').click()
        return CouponSearchPage(self.client)

    def search_vip_detail(self):
        """
        搜索VIP
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/ll_user_info').click()
        from cash_pos.page.security_page.vip_search_page import VipSearchPage
        return VipSearchPage(self.client)

    def return_back(self):
        """
        返回购物车
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_back').click()

    def use_balance(self, balance_value: str):
        """
        使用余额
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/useBalanceButton').click()
        self.driver.implicitly_wait(3)
        keyboard_element = self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/keyboard_input')
        width = keyboard_element.size['width']
        height = keyboard_element.size['height']
        from_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(1).split(',')
        to_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(2).split(',')
        from_x, from_y, to_x, to_y = int(from_element_location[0]), int(from_element_location[1]), int(to_element_location[0]), int(to_element_location[1])
        unit_x, unit_y = int(width / 3), int(height / 4)
        for num in balance_value:
            if num.isdigit() and int(num) != 0:
                x = from_x + ((int(num) % 3 if int(num) % 3 != 0 else 3) - 1) * unit_x + 30
                step = (int(num)) // 3 if (int(num)) % 3 != 0 else (int(num)) // 3 - 1
                y = from_y + step * unit_y + 16
            elif num.isdigit() and int(num) == 0:
                x = from_x + unit_x + 16
                y = from_y + 3 * unit_y + 16
            else:
                x = from_x + 16
                y = from_y + 3 * unit_y + 16
            actions = ActionChains(self.driver)
            actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
            # 计算X,Y值
            actions.w3c_actions.pointer_action.move_to_location(x, y)
            actions.w3c_actions.pointer_action.pointer_down()
            actions.w3c_actions.pointer_action.pause(0.1)
            actions.w3c_actions.pointer_action.release()
            actions.perform()
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_submit').click()
        return self

    def action_use_business_discount(self):
        """
        使用商家折扣（使用折扣时一定要使用店长ID）
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/btn_shop_discount_type_1').click()
        return self

    def small_change(self):
        """
        抹零
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/btn_shop_discount_type_2').click()
        return self

    """
    Service Function
    """

    def insert_money(self,number:str):
        """
        输入金额
        Params:
        -num：金额
        """
        keyboard_element = self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/keyboard_input')
        width = keyboard_element.size['width']
        height = keyboard_element.size['height']
        from_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(1).split(',')
        to_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(2).split(',')
        from_x, from_y, to_x, to_y = int(from_element_location[0]), int(from_element_location[1]), int(to_element_location[0]), int(to_element_location[1])
        unit_x, unit_y = int(width / 3), int(height / 4)
        for num in number:
            if num.isdigit() and int(num) != 0:
                x = from_x + ((int(num) % 3 if int(num) % 3 != 0 else 3) - 1) * unit_x + 30
                step = (int(num)) // 3 if (int(num)) % 3 != 0 else (int(num)) // 3 - 1
                y = from_y + step * unit_y + 16
            elif num.isdigit() and int(num) == 0:
                x = from_x + unit_x + 16
                y = from_y + 3 * unit_y + 16
            else:
                x = from_x + 16
                y = from_y + 3 * unit_y + 16
            actions = ActionChains(self.driver)
            actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
            # 计算X,Y值
            actions.w3c_actions.pointer_action.move_to_location(x, y)
            actions.w3c_actions.pointer_action.pointer_down()
            actions.w3c_actions.pointer_action.pause(0.1)
            actions.w3c_actions.pointer_action.release()
            actions.perform()

    def time_wait(self, time):
        """
        等待
        Params:
        -time:时间
        """
        self.driver.implicitly_wait(time)
        return self

    def screen_shoot(self, filename, path):
        """
        屏幕截图
        Params:
        -filename:文件名称
        -path:路径
        """
        CommonFunction(self.driver).screen_shoot(filename=filename, path=path)
        return self

    def pay_out(self, pay_detail: PayDetail):
        """
        支付
        Params:
        -pay_detail: 支付细节
        """
        pay_way, payment_method = pay_detail.pay_way, pay_detail.payment_method
        receipt_count = 1  # 分单人数
        payment_method = pay_detail.payment_method
        pay_money=pay_detail.money# 结账方式
        if pay_way == PayWay.entire_pay.value:
            # 整单支付
            self.select_payment_method(payment_method,pay_money)
        else:
            # AA支付
            # TODO 需要配置分菜后的逻辑
            pass
        self.driver.implicitly_wait(3)
        return self

    def amount_receivable(self):
        """
        获取应收金额
        """
        remaining_receipts = self.driver.find_elements(AppiumBy.ID, f'{SWITCH_ENV}:id/tvAmountReceivable')
        if len(remaining_receipts) > 0:
            return remaining_receipts[0].text.replace(',', '.').replace('€', '')
        return None

    def select_payment_method(self, payment_method,money=None):
        """
        选择结账方式
        Params:
        -payment_method: 结账方式
        """
        if payment_method == PaymentMethod.cash.value:
            self.driver.find_element(AppiumBy.XPATH,
                                     f'//android.view.ViewGroup[@resource-id="{SWITCH_ENV}:id/cl_cash_pay"]').click()
            self.select_money(money)
        elif payment_method == PaymentMethod.card.value:
            self.driver.find_element(AppiumBy.XPATH,
                                     f'//android.view.ViewGroup[@resource-id="{SWITCH_ENV}:id/cl_bank_pay"]').click()
            self.select_money(money)
        elif payment_method == PaymentMethod.takeout.value:
            self.driver.find_element(AppiumBy.XPATH,
                                     f'//android.view.ViewGroup[@resource-id="{SWITCH_ENV}:id/cl_takeout_pay"]').click()
            payment_method_elements = self.driver.find_elements(AppiumBy.XPATH,
                                                                f'//android.widget.TextView[@resource-id="{SWITCH_ENV}:id/item_tv_title"]')
            # 随机选中某个支付方式
            random_num = random.randint(1, len(payment_method_elements))
            payment_method_elements[random_num - 1].click()
        else:
            self.driver.find_element(AppiumBy.XPATH,
                                     f'//android.view.ViewGroup[@resource-id="{SWITCH_ENV}:id/cl_other_pay_view"]').click()
            payment_method_elements = self.driver.find_elements(AppiumBy.XPATH,
                                                                f'//android.widget.TextView[@resource-id="{SWITCH_ENV}:id/item_tv_title"]')
            # 随机选中某个支付方式
            random_num = random.randint(1, len(payment_method_elements))
            payment_method_elements[random_num - 1].click()

    def select_money(self,money=None):
        """
        选择具体支付钱币
        """
        pay_value = self.driver.find_element(AppiumBy.XPATH,
                                             f'//android.widget.TextView[@resource-id="{SWITCH_ENV}:id/tv_input_num"]').text if not money else str(money)
        self.insert_money(pay_value)
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_submit').click()

    def business_page_insert_number(self, num, type):
        """
        商家优惠页填入数字（这里的Tab选项为任意，并不会区分是固定折扣还是固定金额）
        Params:
        -num:数字
        -type:折扣
        """
        if type == BusinessDiscountType.fixdiscount.value:
            if int(num) < 0 or int(num) > 100:
                raise Exception('输入的金额有误！')
        keyboard_element = self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/keyboard_input')
        width = keyboard_element.size['width']
        height = keyboard_element.size['height']
        from_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(1).split(',')
        to_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", keyboard_element.get_attribute("bounds")).group(2).split(',')
        from_x, from_y, to_x, to_y = int(from_element_location[0]), int(from_element_location[1]), int(to_element_location[0]), int(to_element_location[1])
        unit_x, unit_y = int(width / 3), int(height / 4)
        for num in num:
            if num.isdigit() and int(num) != 0:
                x = from_x + ((int(num) % 3 if int(num) % 3 != 0 else 3) - 1) * unit_x + 30
                step = (int(num)) // 3 if (int(num)) % 3 != 0 else (int(num)) // 3 - 1
                y = from_y + step * unit_y + 16
            elif num.isdigit() and int(num) == 0:
                x = from_x + unit_x + 16
                y = from_y + 3 * unit_y + 16
            else:
                x = from_x + 16
                y = from_y + 3 * unit_y + 16
            actions = ActionChains(self.driver)
            actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
            # 计算X,Y值
            actions.w3c_actions.pointer_action.move_to_location(x, y)
            actions.w3c_actions.pointer_action.pointer_down()
            actions.w3c_actions.pointer_action.pause(0.1)
            actions.w3c_actions.pointer_action.release()
            actions.perform()
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_submit').click()
        return PayOutPage(self.client)
